package com.seele.tigerwallet.ui.manager;

import android.os.HandlerThread;
import android.os.Message;
import android.text.TextUtils;
import android.util.Log;

import com.seele.base.utils.DeviceUtils;
import com.seele.base.utils.LogUtils;
import com.seele.base.utils.PingUtils;
import com.seele.tigerwallet.api.APIException;
import com.seele.tigerwallet.api.APIModule;
import com.seele.tigerwallet.api.APIObjectCallBack;
import com.seele.tigerwallet.model.AddWalletModel;
import com.seele.tigerwallet.model.ExchangerateModel;
import com.seele.tigerwallet.model.FailureErrorModel;
import com.seele.tigerwallet.model.LoginHost;
import com.seele.tigerwallet.model.TokenInfoModel;
import com.seele.tigerwallet.model.UserInfo;
import com.seele.tigerwallet.model.UserInfo.OnUserInfoListener;
import com.seele.tigerwallet.model.UuidModel;
import com.seele.tigerwallet.ui.callback.OnLoginResponseListener;
import com.seele.tigerwallet.ui.utils.BaseUtil;
import com.seele.tigerwallet.ui.utils.GsonUtil;
import com.seele.tigerwallet.ui.utils.SPUtils;
import com.seele.tigerwallet.ui.utils.SqlUtil;

import java.util.List;

import retrofit2.Call;

import static android.os.Handler.*;

/**
 * 用户登录管理类
 */
public class LoginManager implements PingUtils.OnAddressResponseListener {
    private static final int EXCHANGERATE = 0X721;//拿取汇率
    private static final int ONRESPONSE = 0X729;//登录成功
    private static final int REGISTERED = 0X727;//注册
    private static final int LOGIN = 0X726;//登录
    private static final int ERROR = 0X725;//失败
    private static final int APIERROR = 0X724;//返回其他错误
    private static final int UNREGISTERED = 0X723;//表示没有APP中没有地址
    private static final int ADDRESSEXIST = 0X732;
    private static String TAG = LoginManager.class.getSimpleName();
    private static final int UPLOAD_ADDRESS = 0X9625;//上传地址
    private static final int INITAPP = 0X731;//初始化APP
    private int flag = 0;
    //    private LoginHost mLoginHost;
    private PingUtils mPingUtils;
    private OnLoginResponseListener mListener;
    private static final String PATH = "config";

    public void setOnResponseListener(OnLoginResponseListener listener) {
        this.mListener = listener;

    }

    private HandlerThread mHandlerThread;
    private android.os.Handler mHandler;

    boolean isUpload = false;//true 表示已经上报服务器

    public LoginManager() {
        mHandlerThread = new HandlerThread("login message receiver", android.os.Process.THREAD_PRIORITY_BACKGROUND);
        mHandlerThread.start();
        mHandler = new android.os.Handler(mHandlerThread.getLooper(), mCallback);
        if (null == mPingUtils) {
            mPingUtils = new PingUtils();
        }
        mPingUtils.init().setOnAddressResponseListener(this);
    }


    //处理消息
    private Callback mCallback = new Callback() {
        @Override
        public boolean handleMessage(Message msg) {
            switch (msg.what) {
                case INITAPP:
                    Log.i("LoginManager", "INITAPP");
                    initApp();
                    break;
                case ADDRESSEXIST:
                    addressExist();
                    break;
                case UNREGISTERED:
                    if (null != mListener) {
                        mListener.onRegisterResponse();
                    }
                    Log.i("LoginManager", "UNREGISTERED");
                    break;

                case EXCHANGERATE:
                    Log.i("LoginManager", "EXCHANGERATE");
                    initExchangerate();
                    break;
                case ONRESPONSE:
                    Log.i("LoginManager", "ONRESPONSE");
                    if (null != mListener) {
                        mListener.onResponse(isUpload);
                    }
                    break;
                case REGISTERED://注册
                    Log.i("LoginManager", "register");
                    register();
                    break;

                case LOGIN://登录
                    Log.i("LoginManager", "login");
                    login();
                    break;
                case UPLOAD_ADDRESS://上报地址给服务器
                    Log.i("LoginManager", "UPLOAD_ADDRESS");
                    uploadAddress();
                    break;
                case APIERROR://上报地址给服务器
                    Object apiObj = msg.obj;
                    if (apiObj instanceof APIException) {
                        APIException apiException = (APIException) apiObj;
                        if (null != mListener) {
                            mListener.onResponseError(apiException);
                        }
                    }
                    break;
                case ERROR:
                    Object obj = msg.obj;
                    if (obj instanceof FailureErrorModel) {
                        FailureErrorModel model = (FailureErrorModel) obj;
                        if (null != mListener) {
                            mListener.onFailureError(model.call, model.t, model.errorCode);
                        }
                    }
                    break;

            }
            return true;
        }
    };


    /**
     * 初始化APP
     */
    private void initApp() {
        APIModule
                .getApi()
                .init()
                .enqueue(new APIObjectCallBack<LoginHost>() {
                    @Override
                    protected void onResponseError(APIException e) {

                    }
                    @Override
                    protected void onFailureError(Call<String> call, Throwable t) {
                        if (TextUtils.isEmpty(UserInfo.get().address)) {
                            mHandler.sendEmptyMessage(UNREGISTERED);
                        } else {
                            mHandler.sendEmptyMessage(ONRESPONSE);
                        }
                    }
                    @Override
                    protected void onResponse(LoginHost response) {
                        if (null != response) {
                            UserInfo.get().hostList = response.loginhost;
                            handlerLoginHost();
                        }
                    }
                });

    }

    /**
     * 处理初始化的loginHost 获取最优秀地址
     */
    private void handlerLoginHost() {
        List<String> loginHost = UserInfo.get().hostList;
        if (null != loginHost && loginHost.size() > 0) {
            onSuccessAddress(loginHost.get(0));
//            mPingUtils.getOptimalAddress(loginHost);
        }
    }


    /**
     * 查询汇率
     */
    private void initExchangerate() {
        APIModule.getApi()
                .exchangerate()
                .enqueue(new APIObjectCallBack<ExchangerateModel>() {
                    @Override
                    protected void onResponseError(APIException e) {
                        sendMessage(e);
                    }

                    @Override
                    protected void onFailureError(Call<String> call, Throwable t) {
                        sendMessage(call, t, EnumLogin.EXCHANGERATE.ordinal());
                    }

                    @Override
                    protected void onResponse(ExchangerateModel response) {
                        if (null != response) {
                            UserInfo.get().exchangerate = response.exchangerate;
                            SPUtils.saveUserInfo(UserInfo.get());
                        }


//                        //判断是否是第一次登录
//                        if (!SPUtils.getBoolean(SPUtils.IS_FIRST_LOGIN, false)) {
//                            mHandler.sendEmptyMessage(INITDATA);
//                        } else {
                        if (!isUpload) {
                            mHandler.sendEmptyMessage(UPLOAD_ADDRESS);
                        } else {
                            mHandler.sendEmptyMessage(ONRESPONSE);
                        }
//                        }

                    }
                });
    }


    private void uploadAddress() {
        if (TextUtils.isEmpty(UserInfo.get().address)) {
            Log.i("LoginManager", "address 为空");
            return;
        }
        String name = BaseUtil.makeToBase64(UserInfo.get().name);
        APIModule
                .getApi()
                .addwallet(UserInfo.get().token, UserInfo.get().address, name)
                .enqueue(new APIObjectCallBack<AddWalletModel>() {
                    @Override
                    protected void onResponse(AddWalletModel response) {
                        if (null != response) {
                            UserInfo.get().token = response.token;
                            SPUtils.saveUserInfo(UserInfo.get());
                            updateState();
                        }

                    }

                    @Override
                    protected void onResponseError(APIException e) {
                        if (null != e && e.code == APIException.ERROR_110) {
                            SqlUtil.updateState(1, UserInfo.get().address);
                            updateState();
                        } else {
                            sendMessage(e);
                        }
                    }

                    @Override
                    protected void onFailureError(Call<String> call, Throwable t) {
                        sendMessage(call, t, EnumLogin.UPLOADADDRESS.ordinal());
                    }
                });
    }


    private void updateState() {
        isUpload = true;
        mHandler.sendEmptyMessage(ONRESPONSE);

    }


    private String getSql(int isUpload, String address) {
        String sql = String.format("UPDATE t_token SET isUpload = '%d' WHERE address ='%s'", isUpload, address);
        LogUtils.d(sql);
        return sql;
    }


    /**
     * 地址注册,返回UUId
     */
    private void register() {
        UserInfo userInfo = UserInfo.get();
        if (null == userInfo) {
            LogUtils.d("没有钱包地址");
            sendMessage(null, null, EnumLogin.REGISTERED.ordinal());
            return;
        }
        if (null != userInfo) {
            if (!TextUtils.isEmpty(userInfo.address)) {
                APIModule.
                        getApi().
                        register(DeviceUtils.getSDKVersionName(), userInfo.address, "1", "1", DeviceUtils.getAndroidID(), DeviceUtils.getMacAddress(), "1")
                        .enqueue(new APIObjectCallBack<UuidModel>() {
                            @Override
                            protected void onResponse(UuidModel response) {
                                if (null != response && !TextUtils.isEmpty(response.uuid)) {
                                    //保存UUID
                                    UserInfo.get().setUuid(response.uuid);
                                    mHandler.sendEmptyMessage(LOGIN);
                                } else {
                                    //TODO  UUID iSNull
                                }
                            }

                            @Override
                            protected void onResponseError(APIException e) {
                                sendMessage(e);
                            }

                            @Override
                            protected void onFailureError(Call<String> call, Throwable t) {
                                sendMessage(call, t, EnumLogin.REGISTERED.ordinal());

                            }
                        });
            }

        }

    }


    //开始登录
    private void start(boolean isCreate) {


        //获取SP中存储的用户信息
        UserInfo userInfo;
        if (isCreate) {
            userInfo = UserInfo.get();
        } else {
            userInfo = UserInfo.get().getUserInfo();
        }
        LogUtils.json(GsonUtil.toJsonString(userInfo));
        if (null == userInfo) {
            userInfo = UserInfo.get();
        }


        //首先初始化拿到loginHost TODO 是否每次登录都需要拿去 loginHost 每次拿去最优的服务器地址
        List<String> hostList = userInfo.hostList;
        if (null != hostList && hostList.size() > 0) {

            onSuccessAddress(hostList.get(0));
//            mPingUtils.getOptimalAddress(hostList);
        } else if (TextUtils.isEmpty(userInfo.loginhost)) {//表示未初始化
            //初始化拿取到
            mHandler.sendEmptyMessage(INITAPP);
            return;
        } else {
            //设置注册的URL
            APIModule.setApiUrl(userInfo.loginhost);
            //跳转至地址注册
            Message message = mHandler.obtainMessage(ADDRESSEXIST);
            mHandler.sendMessage(message);
        }

    }


    public void create() {
        start(true);

    }

    public void reLogin() {
        start(false);

    }

    /**
     * 判断地址是否为空
     */
    private void addressExist() {
        try {
            String address = UserInfo.get().address;
            //当address为空,表示用户是第一次登录APP,需要注册跳转注册页面
            if (TextUtils.isEmpty(address)) {
                Message message = mHandler.obtainMessage(UNREGISTERED);//返回注册
                mHandler.sendMessage(message);
                return;
            } else {
                List<TokenInfoModel> tokenInfoModels = DaoManager.getTokenDao().queryBuilder().where().eq("address", UserInfo.get().address).query();
                if (tokenInfoModels.size() > 1) {
                    return;
                }
                if (null != tokenInfoModels && tokenInfoModels.size() == 1) {
                    TokenInfoModel tokenInfoModel = tokenInfoModels.get(0);
                    isUpload = tokenInfoModel.isUpload;
                    LogUtils.d("地址是否已经注册::" + isUpload);
                }

            }
            // TODO 拿取本地的UUI
            String UuId = UserInfo.get().getUuid();
            if (TextUtils.isEmpty(UuId)) {//表示为注册
                Message message = mHandler.obtainMessage(REGISTERED);
                mHandler.sendMessage(message);
            } else {
                Message message = mHandler.obtainMessage(LOGIN);
                mHandler.sendMessage(message);

            }

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 登录
     */
    private void login() {
        UserInfo
                .get()
                .login(new OnUserInfoListener() {
                    @Override
                    public void onResponse(UserInfo userInfo) {
                        if (null != userInfo) {

                            if (!TextUtils.isEmpty(userInfo.fronthost)) {//设置业务地址
                                APIModule.setFrontUrl(userInfo.fronthost);
                            }

                            if (!TextUtils.isEmpty(userInfo.token)) {
                                mHandler.sendEmptyMessage(EXCHANGERATE);
                            }
                        }
                    }

                    @Override
                    public void onResponseError(Throwable throwable) {
                        APIModule.setFlag(true);
                        if (throwable instanceof APIException) {
                            APIException apiException = (APIException) throwable;
                            if (apiException.code == APIException.ERROR_112) {
                                mHandler.sendEmptyMessage(REGISTERED);
                            }
                        }
//                        mHandler.sendEmptyMessage(INIT);
                    }

                    @Override
                    public void onFailureError(Call call, Throwable t) {
                        APIModule.setFlag(true);
                        flag += 1;
                        if (flag > 1) {
                            Message message = mHandler.obtainMessage(ERROR);
                            message.arg1 = EnumLogin.INIT.ordinal();
                            mHandler.sendMessage(message);
                        } else {
                            sendMessage(call, t, EnumLogin.LOGIN.ordinal());
                        }
                    }
                });
    }

    /**
     * 发送消息
     *
     * @param call
     * @param t
     * @param code
     */
    private void sendMessage(Call<String> call, Throwable t, int code) {
        Message message = mHandler.obtainMessage(ERROR);
        FailureErrorModel failureErrorModel = new FailureErrorModel();
        failureErrorModel.call = call;
        failureErrorModel.t = t;
        failureErrorModel.errorCode = code;
        message.obj = failureErrorModel;
        mHandler.sendMessage(message);
    }


    private void sendMessage(APIException call) {
        Message message = mHandler.obtainMessage(APIERROR);
        message.obj = call;
        mHandler.sendMessage(message);
    }


    @Override
    public void onErrorAddress() {
        //返回未知错误,直接拿去返回的loginHost取第一位
        List<String> loginHost = UserInfo.get().hostList;
        if (null != loginHost && loginHost.size() > 0) {
            if (!TextUtils.isEmpty(loginHost.get(0))) {
                UserInfo.get().loginhost = loginHost.get(0);
                //设置URL
                APIModule.setApiUrl(UserInfo.getApiUrl(loginHost.get(0)));
                saveUsetInfo(UserInfo.getApiUrl(loginHost.get(0)));
                Message message = mHandler.obtainMessage(ADDRESSEXIST);
                mHandler.sendMessage(message);
            }
        } else if (TextUtils.isEmpty(UserInfo.get().address)) {
            Message message = mHandler.obtainMessage(UNREGISTERED);//返回注册
            mHandler.sendMessage(message);
        } else {
            LogUtils.aTag("地址错误");
        }


    }

    @Override
    public void onSuccessAddress(String address) {
        //返回最优的地址
        LogUtils.dTag("onSuccessAddress", "address::" + address);
        saveUsetInfo(address);
        APIModule.setApiUrl(address);
        Message message = mHandler.obtainMessage(ADDRESSEXIST);
        mHandler.sendMessage(message);


    }

    /**
     * 中途保存用户信息
     *
     * @param address
     */
    private void saveUsetInfo(String address) {
        UserInfo.get().loginhost = address;
        SPUtils.saveUserInfo(UserInfo.get());
    }


    private enum EnumLogin {
        INIT, REGISTERED, LOGIN, EXCHANGERATE, INITDATA, UPLOADADDRESS;
    }


}